// file name: new_inst_test.h
#include <cpu_cde.h>

#define concat_tmp(x,y) x ## y
#define concat(x,y) concat_tmp(x,y)
#define is_tow_reg_equ(reg_a,reg_b) \
    bne reg_a,reg_b,inst_error; \
    nop;

#define is_reg_equ_to_imm(reg_a,reg_tmp,imm) \
    LI (reg_tmp,imm); \
    bne reg_a,reg_tmp,inst_error; \
    nop;

#define TEST_CLZ(in_a, ref_ans) \
    LI (t0, in_a);\
    clz   v0, t0; \
    LI (t1, ref_ans);\
    bne   t1, v0, inst_error; \
    nop;

#define TEST_CLZ_SPECIAL \
    LI (t0,0); \
    clz t1,t0; \
    clz t2,t1; \
    clz t3,t2; \
    clz t4,t3; \

#define TEST_CLO(in_a, ref_ans) \
    LI (t0, in_a);\
    LI (t1, ref_ans);\
    clo   v0, t0; \
    bne   t1, v0, inst_error; \
    nop;

#define TEST_CLO_SPECIAL \
    LI (t0,0xffffffff); \
    clo t1,t0; \
    clo t2,t0; \
    clz t3,t2; \
    nop;

#define TEST_MUL_1(a,b) \
    LI (t0,a); \
    LI (t1,b); \
    mult t0,t1; \
    mflo t2; \
    mul t3,t0,t1; \
    nop;

#define TEST_bypass_Rtype_src0_1(instr,c,a,b) \
    or t1,zero,b; \
    or t0,zero,a; \
    instr t2,t0,t1; \

#define TEST_bypass_Rtype_src0_2(instr,c,a,b) \
    or t0,zero,a; \
    or t1,zero,b; \
    instr t2,t0,t1; \

#define TEST_bypass_Rtype_src0_3(instr,c,a,b) \
    or t0,zero,a; \
    or t1,zero,b; \
    or t2,zero,0x8888; \
    instr t3,t0,t1; \

#define TEST_bypass_Rtype_src0_4(instr,c,a,b) \
    or t0,zero,a; \
    or t4,zero,0x4444; \
    or t1,zero,b; \
    or t2,zero,0x8888; \
    instr t3,t0,t1; \

#define TEST_bypass_Rtype_src1_1(instr,c,a,b) \
    or t0,zero,a; \
    or t1,zero,b; \
    instr t2,t0,t1; \

#define TEST_bypass_Rtype_src1_2(instr,c,a,b) \
    or t1,zero,b; \
    or t0,zero,a; \
    instr t2,t0,t1; \

#define TEST_bypass_Rtype_src1_3(instr,c,a,b) \
    or t1,zero,b; \
    or t0,zero,a; \
    or t2,zero,0x8888; \
    instr t3,t0,t1; \

#define TEST_bypass_Rtype_src1_4(instr,c,a,b) \
    or t1,zero,b; \
    or t4,zero,0x4444; \
    or t0,zero,a; \
    or t2,zero,0x8888; \
    instr t3,t0,t1; \

#define TEST_bypass_Rtype_dst0_1(instr,c,a,b) \
    or t0,zero,a; \
    or t1,zero,b; \
    instr t2,t0,t1; \
    or t3,t2,zero; \

#define TEST_bypass_Rtype_dst0_2(instr,c,a,b) \
    or t1,zero,b; \
    or t0,zero,a; \
    instr t2,t0,t1; \
    or t4,zero,0x3333; \
    or t3,t2,zero; \

#define TEST_bypass_Rtype_dst0_3(instr,c,a,b) \
    or t1,zero,b; \
    or t0,zero,a; \
    instr t2,t0,t1; \
    or t5,zero,0x4444; \
    or t4,zero,0x3333; \
    or t3,t2,zero; \

#define TEST_bypass_Rtype_dst0_4(instr,c,a,b) \
    or t1,zero,b; \
    or t0,zero,a; \
    instr t2,t0,t1; \
    or t5,zero,0x4444; \
    or t4,zero,0x3333; \
    or t6,zero,0x2222; \
    or t3,t2,zero; \

#define TEST_bypass_Rtype_dst1_1(instr,c,a,b) \
    or t0,zero,a; \
    or t1,zero,b; \
    instr t2,t0,t1; \
    or t3,zero,t2; \

#define TEST_bypass_Rtype_dst1_2(instr,c,a,b) \
    or t1,zero,b; \
    or t0,zero,a; \
    instr t2,t0,t1; \
    or t4,zero,0x3333; \
    or t3,zero,t2; \

#define TEST_bypass_Rtype_dst1_3(instr,c,a,b) \
    or t1,zero,b; \
    or t0,zero,a; \
    instr t2,t0,t1; \
    or t5,zero,0x4444; \
    or t4,zero,0x3333; \
    or t3,zero,t2; \

#define TEST_bypass_Rtype_dst1_4(instr,c,a,b) \
    or t1,zero,b; \
    or t0,zero,a; \
    instr t2,t0,t1; \
    or t5,zero,0x4444; \
    or t4,zero,0x3333; \
    or t6,zero,0x2222; \
    or t3,zero,t2; \

#define Test_Rtype(instr,c,a,b) \
    TEST_bypass_Rtype_src0_1(instr,c,a,b) \
    TEST_bypass_Rtype_src0_2(instr,c,a,b) \
    TEST_bypass_Rtype_src0_3(instr,c,a,b) \
    TEST_bypass_Rtype_src0_4(instr,c,a,b) \
    TEST_bypass_Rtype_src1_1(instr,c,a,b) \
    TEST_bypass_Rtype_src1_2(instr,c,a,b) \
    TEST_bypass_Rtype_src1_3(instr,c,a,b) \
    TEST_bypass_Rtype_src1_4(instr,c,a,b) \
    TEST_bypass_Rtype_dst0_1(instr,c,a,b) \
    TEST_bypass_Rtype_dst0_2(instr,c,a,b) \
    TEST_bypass_Rtype_dst0_3(instr,c,a,b) \
    TEST_bypass_Rtype_dst0_4(instr,c,a,b) \
    TEST_bypass_Rtype_dst1_1(instr,c,a,b) \
    TEST_bypass_Rtype_dst1_2(instr,c,a,b) \
    TEST_bypass_Rtype_dst1_3(instr,c,a,b) \
    TEST_bypass_Rtype_dst1_4(instr,c,a,b) \

#define TEST_MType(immA,immB,resultLo,resultHi,originA,originB,instr) \
    LI (t0,immA); \
    LI (t1,immB); \
    LI (t2,originA); \
    LI (t3,originB); \
    mthi t3; \
    mtlo t2; \
    instr t0,t1; \
    mfhi t4; \
    mflo t5; \


#define TEST_MOVN_TRUE(immA,is_true) \
    LI (t0,is_true); \
    LI (t2,immA); \
    LI (t1,0x8888888); \
    movn t1,t2,t0; \

#define TEST_MOVN_FALSE(immA) \
    LI (t2,immA); \
    LI (t1,0x8888888); \
    movn t1,t2,zero; \


#define TEST_MOVZ_FALSE(immA) \
    LI (t2,immA); \
    LI (t1,0x8888888); \
    movz t1,t2,t2; \

#define TEST_MOVZ_TRUE(immA) \
    LI (t2,immA); \
    LI (t1,0x8888888); \
    movz t1,t2,zero; \

#define TEST_TRAP_HAPPEN(instr,imm_reg,imm,tag) \
    LI (s2,0); \
    li t0,imm_reg; \
    la s4,tag; \
tag: \
    instr t0,imm; \
    nop

#define TEST_TRAP_NOT_HAPPEN(instr,imm_reg,imm,tag) \
    LI (s2,0); \
    li t0,imm_reg; \
    la s4,tag; \
tag: \
    instr t0,imm; \
    nop

#define TEST_BAL(immA,immB,tag) \
    li t0,immA; \
    li t7,immB; \
    bal tag; \
    or t1,t7,zero; \
    li t1,0xfa09e; \
tag: \
    nop

#define TEST_BEQ_LIKE(immA,immB,dont_jump,jump) \
    li t7,immB; \
    li t0,0x1; \
    li t1,immA; \
    beql zero,t0, dont_jump; \
    or t1,zero,t7; \
dont_jump: \
    li t0,immA; \
    li t7,immB; \
    beql zero,zero,jump; \
    or t1,t7,immB; \
    li t0,immB; \
    li t1,immA; \
jump: \
    nop

#define TEST_BNE_LIKE(immA,immB,dont_jump,jump) \
    li t0,0x1; \
    li t7,immB; \
    li t1,immA; \
    bnel zero,t0,jump; \
    or t1,zero,t7; \
jump: \
    li t0,immA; \
    li t7,immA; \
    bnel zero,zero,dont_jump; \
    or t1,t7,zero; \
    li t0,immB; \
dont_jump: \
    nop

#define TEST_BRANCH_LIKE(instr,immA,immB,dont_jump,jump) \
    li t0,0xaaa; \
    li t1,0xbbb; \
    li t2,immA; \
    instr t2,dont_jump; \
    ori t0,zero,0xcccc; \
dont_jump: \
    li t1,0x111; \
    li t0,0xef; \
    li t2,immB; \
    instr t2,jump; \
    ori t1,zero,0xeee; \
    li t0,0xfca; \
jump: \
    nop

#define TEST_BRANCH_LINK_LIKE(instr,immA,immB,dont_jump,jump) \
    li t0,0xaaa; \
    li t1,0xbbb; \
    li t2,immA; \
    instr t2,dont_jump; \
    ori t0,zero,0xcccc; \
dont_jump: \
    li t1,0x111; \
    li t0,0xef; \
    li t2,immB; \
    la t4,jump; \
    instr t2,jump; \
    ori t1,zero,0xeee; \
    li t0,0xfca; \
jump: \
    nop
